﻿package com.zouloux.ui 
{
	import com.zouloux.abstract.IComponent;
	import com.zouloux.utils.Debug;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import com.greensock.easing.Strong;
	import com.greensock.TweenMax;
	import flash.text.TextField;
	
	/**
	 * ...
	 * @author ZoulouX
	 */
	public class ComboBox extends Component implements IComponent
	{
		// Le champs texte
		public var $button						:ClassicButton;
		
		// La flèche
		public var $arrow						:Sprite;
		
		// La classe des items
		protected var _itemClass				:Class;
		
		// Pour savoir si la combo est ouverte
		protected var _opened					:Boolean				= false;
		
		// Le menu
		protected var _menu						:Array;
		
		// Le masque du menu
		protected var _mask						:Sprite;
		protected var _menuMc					:Sprite;
		
		// Les données
		protected var _selectedItem				:ComboBoxItem;
		
		// La liste des items
		protected var _items					:Array;
		
		// Les données
		protected var _data						:*;
		
		// La direction de l'ouverture
		protected var _direction				:String						= "auto";
		
		
		// Les tweens
		protected var _tweenMenuOpen			:TweenConfig 				= new TweenConfig(Strong.easeOut, .5, {});
		protected var _tweenMenuClose			:TweenConfig 				= new TweenConfig(Strong.easeOut, .5, {});
		protected var _tweenArrowOpen			:TweenConfig 				= new TweenConfig(Strong.easeOut, .5, {rotation: 0});
		protected var _tweenArrowClose			:TweenConfig 				= new TweenConfig(Strong.easeOut, .5, {rotation: -180});
		
		
		// Les getters
		public function get label ():String
		{
			return $button.title;
		}
		public function get opened ():Boolean
		{
			return _opened;
		}
		public function get menu ():Array
		{
			return _menu;
		}
		public function get selectedItem ():ComboBoxItem
		{
			return _selectedItem;
		}
		public function get items():Array
		{
			return _items;
		}
		public function get data():*
		{
			return _data;
		}
		public function get tweenMenuOpen():TweenConfig
		{
			return _tweenMenuOpen;
		}
		public function get tweenMenuClose():TweenConfig
		{
			return _tweenMenuClose;
		}
		public function get tweenArrowOpen():TweenConfig
		{
			return _tweenArrowOpen;
		}
		public function get tweenArrowClose():TweenConfig
		{
			return _tweenArrowClose;
		}
		public function get itemClass():Class
		{
			return _itemClass;
		}
		
		
		// Les setters
		public function set label (value:String):void
		{
			$button.title = value;
		}
		public function set opened (value:Boolean):void 
		{
			// Enregistrer la valeur
			_opened = value;
			
			// Agir
			if (_opened)
				open();
			else
				close();
		}
		public function set menu (value:Array):void 
		{
			// Enregistrer la valeur
			_menu = value;
			
			// Reconstruire le menu
			buildMenu();
		}
		public function set selectedItem (value:ComboBoxItem):void
		{
			// Attribuer la valeur
			_selectedItem = value;
			
			// Récupérer son label et son data
			label = value.label;
			data = value.data;
			
			// Dispatcher l'event
			dispatchEvent(new Event(Event.CHANGE));
		}
		public function set items(value:Array):void 
		{
			_items = value;
		}
		public function set data(value:*):void 
		{
			_data = value;
		}
		public function set tweenMenuOpen(value:TweenConfig):void 
		{
			_tweenMenuOpen = value;
		}
		public function set tweenMenuClose(value:TweenConfig):void 
		{
			_tweenMenuClose = value;
		}
		public function set tweenArrowOpen(value:TweenConfig):void 
		{
			_tweenArrowOpen = value;
		}
		public function set tweenArrowClose(value:TweenConfig):void 
		{
			_tweenArrowClose = value;
		}
		public function set itemClass(value:Class):void 
		{
			_itemClass = value;
		}
		
		
		// Le constructeur
		public function ComboBox () 
		{
			// Appeler le constructeur parent
			super("ComboBox");
			
			// Vérifier si on a un clip button
			if ($button == null)
				throw new Error("Warning, missing $button in ComboBox");
			
			// Désactiver le curseur sur la flèche
			if ($arrow != null)
				$arrow.mouseEnabled = false;
		}
		
		// Initialisation
		override protected function init (event:Event = null):void
		{
			Debug.add("com.zouloux.ui.ComboBox.initComboBox()");
			
			// Ecouter les clicks
			$button.addEventListener(MouseEvent.CLICK, clickHandler);
			
			// Ecouter les clicks en dehors
			stage.addEventListener(MouseEvent.CLICK, close);
		}
		
		// La méthode pour construire le menu
		protected function buildMenu ():void
		{
			Debug.add("com.zouloux.ui.ComboBox.buildMenu()");
			
			// Tuer l'ancien clip s'il existe
			if (_menuMc != null)
			{
				removeChild(_mask);
				removeChild(_menuMc);
			}
			
			// Recréer la liste des items
			_items = [];
			
			// Créer le menu
			_menuMc = new Sprite();
			
			// Lire les propriété
			var total:uint = _menu.length;
			for (var i:uint = 0; i < total; i++)
			{
				// Créer le bouton
				var item:ComboBoxItem = new ComboBoxItem();
				
				// Définir le label
				if (_menu[i].label != null)
					item.label = _menu[i].label;
				
				// Définir le data
				if (_menu[i].data != null)
					item.data = _menu[i].data;
				
				// Ajouter dans le menu
				_menuMc.addChild(item);
				
				// Le placer
				item.y = item.height * i;
				
				// Ajouter à la liste des items
				_items.push(item);
				
				// Ecouter les clicks
				item.addEventListener(MouseEvent.CLICK, selectItem);
			}
			
			// Ajouter le menu
			addChild(_menuMc);
			
			// Créer le masque
			_mask = new Sprite();
			
			// Ajouter le mask
			addChild(_mask);
			
			// Le dessiner
			_mask.graphics.beginFill(0x00FF00, 1);
			_mask.graphics.drawRect(0, 0, _menuMc.width, -_menuMc.height);
			_mask.graphics.endFill();
			
			// L'appliquer au menu
			_menuMc.mask = _mask;
			
			// Séléctionner le premier
			if (_items[0] != null)
				selectedItem = _items[0];
		}
		
		// Séléction d'un item
		protected function selectItem (event:MouseEvent):void
		{
			selectedItem = (event.target as ComboBoxItem);
		}
		
		// Lorsqu'on clique quelquepart
		protected function clickHandler (event:MouseEvent = null):void
		{
			// Inverser
			toggle();
		}
		
		// Faire sortir
		public function open (event:MouseEvent = null):void
		{
			// Vérifier
			if (!_opened)
			{
				// Spécifier l'état
				_opened = true;
				
				// La flèche
				if ($arrow != null)
					_tweenArrowOpen.to($arrow);
				
				// Le menu
				if (_menuMc != null)
					_tweenMenuOpen.to(_menuMc, { y: -_menuMc.height } );
			}
		}
		
		// Faire entrer
		public function close (event:MouseEvent = null):void
		{
			// S'il y a un event et si c'est pas ce clip
			if ((event != null && event.target != $button) || event == null)
			{
				// Vérifier que ça ne soit pas déjà fermé
				if (_opened)
				{
					// Spécifier l'état
					_opened = false;
					
					// La flèche
					if ($arrow != null)
						_tweenArrowClose.to($arrow);
					
					// Le menu
					if (_menuMc != null)
						_tweenMenuClose.to(_menuMc, { y: 0 } );
				}
			}
			
		}
		
		// Inverser l'état
		public function toggle (event:Event = null):void
		{
			_opened ? close() : open();
		}
		
		// Ajouter un élément
		public function addItem (pItem:*):uint
		{
			// Vérifier le type de l'item
			if (pItem is Array)
			{
				
			}
			else if (pItem is ComboBoxItem)
			{
				
			}
			else
			{
				throw new Error("");
			}
			
			return 0;
		}
		
		// Ajouter un élément à une certaine place
		public function addItemAt (pItem:*, pAt:uint):void
		{
			// Vérifier le type de l'item
			if (pItem is Array)
			{
				
			}
			else if (pItem is ComboBoxItem)
			{
				
			}
			else
			{
				throw new Error("");
			}
		}
		
		// Virer un élément
		public function removeItem (pItem:*):uint
		{
			// Vérifier le type de l'item
			if (pItem is Array)
			{
				
			}
			else if (pItem is ComboBoxItem)
			{
				
			}
			else
			{
				throw new Error("");
			}
			
			return 0;
		}
		
		// Vérifier un élément à une place précise
		public function removeItemAt (pAt:uint):void
		{
			
		}
	}
}